package com.kyhd.audio.service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kyhd.audio.dao.model.Novel;
import com.kyhd.audio.util.AppConfig;
import com.kyhd.audio.util.InitConst;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class AudioExchangeService {
	
	@Autowired
	RedisService redisService;

	@Autowired
	NovelService novelService;
	
	@Autowired
	AppConfig appconfig;
	
	@Autowired
	OSSService ossService;
	
	@Autowired
	AudioExchangeLogService audioExchangeLogService;
	
	@Autowired
	SpeechService speechService;
	
	public void sendMsg(String ids) {
		if(ids!=null&&!"".equals(ids)) {
			this.sendMsgByIds(ids, false);
		}else {
			this.sendMsgDefault();
		}
	}
	
	public void sendMsgByIds(String ids, boolean handle) {
		String[] novelIds = ids.split(",");
		for (String novelId : novelIds) {
			List<String> contentIds = this.novelService.getByNovelId(novelId);
			for (String contentId : contentIds) {
				if(handle) {
					this.redisService.sendMsg(InitConst.NOVELHAND, contentId);
					try {
						Thread.sleep(100); //防止一秒之内发布消息过多导致数据库链接池消耗空
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}else {
					this.redisService.sendMsg(InitConst.NOVELSTART, contentId);
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	public void sendMsgDefault() {
		List<Novel> novels = this.novelService.getNovelIdsByNum(Integer.valueOf(this.appconfig.getDefaultNovelNum()));
		for (Novel novel : novels) {
			List<String> contentIds = this.novelService.getByNovelId(novel.getContent_novel_id());
			for (String contentId : contentIds) {
				this.redisService.sendMsg(InitConst.NOVELSTART, contentId);
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void receiveMsgHandle(String message) {
		log.info("receive message contentId:{}",message);
		if(message!=null) {
			Novel novel = this.novelService.getByContentId(message);
			if(novel!=null&&novel.getAudio()==0) {
				byte[] byteContent = new byte[0];
				String content = novel.getContent()	
						.replace("{#lt}", "")
						.replace("br", "")
						.replace("/", "")
						.replace("{#gt}", "");
//				log.info(content);
				//调用百度API 生成音频文件流
				int length = content.length();
				int times = length/510; //少于1024个字节
				if(times<=1) {
					byteContent = this.speechService.synthesis(content);
				}else {
					for (int i = 0; i <= times; i++) {
						int s = 510*i;
						int e = 510*(i+1);
						if(e>length) {
							e = length;
						}
						String partContent = content.substring(s, e);
						byte[] byteContentPart = this.speechService.synthesis(partContent);
						byteContent = addBytes(byteContent,byteContentPart);
					}
				}
				if(byteContent!=null) {
					//将音频文件上传到OSS
					InputStream in = new ByteArrayInputStream(byteContent);
					String path = this.ossService.uploadCommon(in, novel.getContent_id()+".mp3");
					if(path!=null) {
						//修改小说表的audio状态
						this.novelService.updateAudio(novel);
						//音频转换日志表添加一条记录
						this.audioExchangeLogService.save(novel,path);
					}
				}
			}
		}
	}
	
	/** 
	 * @param data1 
	 * @param data2 
	 * @return data1 与 data2拼接的结果 
	 */
	public static byte[] addBytes(byte[] data1, byte[] data2) {
		byte[] data3 = null;
		if(data1==null||data1.length<=0) {
			data3 = data2;
		}else {
			data3 = new byte[data1.length + data2.length]; 
			System.arraycopy(data1, 0, data3, 0, data1.length);
			System.arraycopy(data2, 0, data3, data1.length, data2.length);
		}
		return data3; 
	}
	
	/**
	 * 使用指定加密类型 生成token
	 * @param inStr
	 * @param type
	 * @return
	 * @throws Exception
	 */
	public String createToken(String inStr, String type) throws Exception {
		MessageDigest md = null;
		String out = null;
		try {
			md = MessageDigest.getInstance(type);
			byte[] digest = md.digest(inStr.getBytes());
			out = byte2hex(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			throw e;
		}
		return out;
	}


	/**
	 * 二进制转化为16进制
	 * @param b
	 * @return
	 */
	private static String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0xFF);
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else {
				hs = hs + stmp;
			}
		}
		return hs.toUpperCase();
	}
}
